package com.ruoyi.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.mapper.SysDeptMapper;
import com.ruoyi.common.core.mapper.SysUserMapper;
import com.ruoyi.common.core.service.BaseServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.kiam.KiamUtil;
import com.ruoyi.entity.SysPost;
import com.ruoyi.entity.SysUserPost;
import com.ruoyi.entity.SysUserRole;
import com.ruoyi.mapper.SysPostMapper;
import com.ruoyi.mapper.SysRoleMapper;
import com.ruoyi.mapper.SysUserPostMapper;
import com.ruoyi.mapper.SysUserRoleMapper;
import jakarta.validation.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.ruoyi.common.framework.aspectj.DataScopeAspect.*;

/**
 * 用户 业务层处理
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> {
    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysPostMapper postMapper;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserPostMapper userPostMapper;

    @Autowired
    protected Validator validator;


    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */

    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUserList(SysUser user) {
        return userMapper.selectUserList(user);
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */

    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectAllocatedList(SysUser user) {
        return userMapper.selectAllocatedList(user);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */

    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUnallocatedList(SysUser user) {
        return userMapper.selectUnallocatedList(user);
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @param userType
     * @return 用户对象信息
     */

    public SysUser selectUserByUserName(String userName, String userType) {
        return userMapper.selectUserByUserName(userName, userType);
    }

    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */

    public SysUser selectUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }

    /**
     * 查询用户所属角色组
     *
     * @param userName 用户名
     * @return 结果
     */

    public String selectUserRoleGroup(String userName) {
        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
        if (CollectionUtils.isEmpty(list)) {
            return StringUtils.EMPTY;
        }

        return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
    }

    /**
     * 查询用户所属岗位组
     *
     * @param userName 用户名
     * @return 结果
     */

    public String selectUserPostGroup(String userName) {
        List<SysPost> list = postMapper.selectPostsByUserName(userName);
        if (CollectionUtils.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */

    public boolean checkUserNameUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkUserNameUnique(user.getUserName());
        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
            Assert.isFalse(true, "新增用户'" + user.getUserName() + "'失败，登录账号已存在");
            return UserConstants.NOT_UNIQUE;
        }

        return UserConstants.UNIQUE;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param user 用户信息
     * @return
     */

    public boolean checkPhoneUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     * @return
     */

    public boolean checkEmailUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SysUser info = userMapper.checkEmailUnique(user.getEmail());
        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */

    public void checkUserAllowed(SysUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && SysUserServiceImpl.isAdmin(user.getUserId())) {
            //throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    /**
     * 校验用户是否有数据权限
     *
     * @param userId 用户id
     */

    public void checkUserDataScope(Long userId) {
        /*if (!isAdmin(SecurityUtils.getUserId())) {
            SysUser user = new SysUser();
            user.setUserId(userId);
            List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
            if (StringUtils.isEmpty(users)) {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }*/
    }

    public static boolean isAdmin(Long userId) {
        SysRoleMapper roleMapper = SpringUtil.getBean(SysRoleMapper.class);
        List<SysRole> roleList = roleMapper.selectRolePermissionByUserId(userId);
        return roleList.stream().filter(r -> "admin".equals(r.getRoleKey())).count() > 0;
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */

    @Transactional
    public int insertUser(SysUser user) {
        if (user.getRoleIds() != null && user.getRoleIds().length > 0) {
            SysRole role = roleMapper.selectById(user.getRoleIds()[0]);
            user.setRoleName(role.getRoleName());
            user.setRoleDeptName(role.getDeptName());
        }
        if (user.getDeptId() != null) {
            SysDept dept = sysDeptMapper.selectById(user.getDeptId());
            user.setDeptName(dept.getDeptName());
            user.setDeptAncestors(dept.getAncestors() + "," + user.getDeptId() + ",");
        }
        if (user.getClearExpert() == null) {
            user.setClearExpert(false);
        }
        setManagerDept(user);
        user.setKeywords(user.getNickName() + " " + user.getPhonenumber());
        // 新增用户信息
        user.insert();
        // 新增用户岗位关联
        insertUserPost(user);
        // 新增用户与角色管理
        insertUserRole(user);
        return 1;
    }

    private void setManagerDept(SysUser user) {
        List<String> managerDeptIdList = new ArrayList<>();
        List<String> managerDeptList = new ArrayList<>();
        String managerDeptValue = user.getManagerDeptValue();
        if (StrUtil.isNotBlank(managerDeptValue)) {
            JSONArray jsonArray = JSONArray.parseArray(managerDeptValue);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONArray deptArray = jsonArray.getJSONArray(i);
                String deptId = deptArray.getString(deptArray.size() - 1);
                SysDept dept = sysDeptMapper.selectById(deptId);
                managerDeptList.add(dept.getDeptName());
                managerDeptIdList.add(deptId);
            }
        }
        user.setManagerDeptIds(managerDeptIdList.stream().collect(Collectors.joining(",")));
        user.setManagerDept(managerDeptList.stream().collect(Collectors.joining(",")));
    }

    /**
     * 注册用户信息
     *
     * @param user 用户信息
     * @return 结果
     */

    public boolean registerUser(SysUser user) {
        user.insert();
        return true;
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */

    @Transactional
    public int updateUser(SysUser user, boolean isSync) {
        //checkOptPermission(user);
        if (user.getRoleId() != null) {
            SysRole role = roleMapper.selectById(user.getRoleId());
            user.setRoleName(role.getRoleName());
        }
        if (user.getDeptId() != null) {
            SysDept dept = sysDeptMapper.selectById(user.getDeptId());
            user.setDeptName(dept.getDeptName());
            user.setDeptAncestors(dept.getAncestors() + "," + user.getDeptId() + ",");
        }

        setManagerDept(user);
        user.setKeywords(user.getNickName() + " " + user.getPhonenumber());
        Long userId = user.getUserId();
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);
        // 新增用户与角色管理
        insertUserRole(user);
        if (!isSync) {
            // 删除用户与岗位关联
            userPostMapper.deleteUserPostByUserId(userId);
            // 新增用户与岗位管理
            insertUserPost(user);
        }
        user.updateById();
        return 1;
    }

    /**
     * 用户授权角色
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */

    @Transactional
    public void insertUserAuth(Long userId, Long roleIds) {
        userRoleMapper.deleteUserRoleByUserId(userId);
        insertUserRole(userId, roleIds);
    }

    /**
     * 修改用户基本信息
     *
     * @return 结果
     */

    public int updateUserProfile(SysUser user) {
        user.updateById();
        return 1;
    }

    /**
     * 修改用户头像
     *
     * @param userName 用户名
     * @param avatar   头像地址
     * @return 结果
     */

    public boolean updateUserAvatar(String userName, String avatar) {
        return userMapper.updateUserAvatar(userName, avatar) > 0;
    }

    /**
     * 重置用户密码
     *
     * @param user 用户信息
     * @return 结果
     */

    public int resetPwd(SysUser user) {
        user.updateById();
        return 1;
    }

    /**
     * 重置用户密码
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
     */

    public int resetUserPwd(String userName, String password) {
        return userMapper.resetUserPwd(userName, password);
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRole(SysUser user) {
        this.insertUserRole(user.getUserId(), user.getRoleId());
    }

    /**
     * 新增用户岗位信息
     *
     * @param user 用户对象
     */
    public void insertUserPost(SysUser user) {
        String postNames = "";
        if (StringUtils.isNotEmpty(user.getPostIds())) {
            String[] posts = user.getPostIds().split(",");
            // 新增用户与岗位管理
            List<SysUserPost> list = new ArrayList<SysUserPost>(posts.length);
            for (String postId : posts) {
                SysPost post = postMapper.selectById(postId);
                postNames += post.getPostName() + ",";
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(Long.valueOf(postId));
                list.add(up);
            }
            user.setPostNames(postNames.substring(0, postNames.length() - 1));
            userPostMapper.batchUserPost(list);
        }
    }

    /**
     * 新增用户角色信息
     *
     * @param userId 用户ID
     */
    public void insertUserRole(Long userId, Long roleId) {
        if (roleId != null) {
            // 新增用户与角色管理
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            ur.insert();
        }
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */

    @Transactional
    public int deleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            checkUserAllowed(new SysUser(userId));
        }
        // 删除用户与角色关联
        userRoleMapper.deleteUserRole(userIds);
        // 删除用户与岗位关联
        userPostMapper.deleteUserPost(userIds);
        return userMapper.deleteUserByIds(userIds);
    }

    public Map<String, Object> getUserInfo() {
        SysUser user = baseMapper.selectById(SecurityUtils.getLoginUser().getUserId());
        Map rs = MapUtil.builder().put("username", user.getUserName()).put("roles", new ArrayList<String>())
                .put("permissions", new String[]{"read:system", "write:system", "delete:system"})
                .put("expertId", user.getExpertId())
                .put("user", user)
                .put("avatar", "https://i.gtimg.cn/club/item/face/img/2/16022_100.gif").build();
        return rs;
    }

    public List<String> getCurrUserDeptAuthority() {
        Long departmentId = SecurityUtils.getLoginUser().getDeptId();    //当前用户部门ID
        List<SysDept> depts = sysDeptMapper.selectAllDeptListByParentId(departmentId);

        List<String> deptIds = depts.parallelStream().map(d -> d.getDeptId() + "").collect(Collectors.toList());
        deptIds.add(departmentId + ""); //增加当前部门ID

        return deptIds;
    }

    /**
     * 增加公告参数
     */
    public static void addSystemParam(Map<String, Object> param) {
        LoginUser user = SecurityUtils.getLoginUserCanNotLogin();
        if (user != null) {
            param.put("userType", user.getUser().getUserType());
            param.put("expertId", user.getUser().getExpertId());
            param.put("userId", user.getUser().getUserId());
            param.put("deptId", user.getUser().getDeptId());
            List<Long> deptIds = null;
            if (user.getUser().getDeptId() != null) {
                SysDeptMapper deptMapper = SpringUtil.getBean(SysDeptMapper.class);
                SysDept dept = deptMapper.selectById(user.getUser().getDeptId());
                if (dept != null) {
                    SysDept rootDept = deptMapper.selectById(dept.getRootDeptId());
                    List<SysDept> children = deptMapper.selectChildrenAndSelfById(rootDept.getDeptId());
                    deptIds = children.parallelStream().map(d -> d.getDeptId()).collect(Collectors.toList());

                    param.put("ancestors", rootDept.getAncestors() + "," + rootDept.getDeptId() + ",");
                    param.put("rootDeptId", rootDept.getDeptId());
                }


            }
            param.put("deptIds", deptIds);
        }
    }

    public static SysDept getRootDept(SysDept dept, SysDeptMapper deptMapper) {
        SysDept parent = deptMapper.selectById(dept.getParentId());
        if (parent == null || !dept.getAdministrativeLevel().equals(parent.getAdministrativeLevel())) {
            return dept;
        } else {
            return getRootDept(parent, deptMapper);
        }
    }

    @DataScope(deptAlias = "t1", userAlias = "t1")
    public void getList(Page page, Map<String, Object> param) {
        addSystemParam(param);
        baseMapper.getList(page, param);
    }

    public void doDelete(Long id) {
        List<Long> deptIds = new ArrayList<Long>();
        deptIds.add(id);
        this.deleteUserByIds(deptIds.toArray(new Long[deptIds.size()]));
    }

    public void updatePhone(String phoneNumber) {
        SysUser user = SecurityUtils.getClientUser();
        SysUser old = userMapper.selectUserById(user.getUserId());
        old.setPhonenumber(phoneNumber);
        old.updateById();
    }

    public void updateLoginUser(SysUser user) {
        user.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
        user.updateById();
    }

    public void buildOpenId(Long userId, String openId) {
        SysUser user = userMapper.selectById(userId);
        user.setOpenId(openId);
        user.updateById();
    }

    public void setBuildWeixin(Integer days) {
        SysUser user = baseMapper.selectById(SecurityUtils.getUserId());
        user.setNotTipsBuildTime(DateUtil.offsetDay(new Date(), days));
        user.updateById();
    }

    public void updateUse(Long userId) {
        SysUser user = userMapper.selectById(userId);
        user.setStatus(user.getStatus().equals("0") ? "1" : "0");
        user.updateById();
    }


    public void syncUser(Long startTime) throws Exception {
        List<SysUser> userList = KiamUtil.syncUser(startTime);
        System.out.println("userList:" + userList.size());
        Long ordinaryBusinessPersonnelRole = roleMapper.checkRoleKeyUnique("OrdinaryBusinessPersonnel").getRoleId();
        Long adminRole = roleMapper.checkRoleKeyUnique("admin").getRoleId();
        for (int i = 0; i < userList.size(); i++) {
            SysUser user = userList.get(i);
            if (user.getKiamOrgId() != null) {
                SysDept dept = sysDeptMapper.getByOrgId(user.getKiamOrgId());
                if (dept != null) {
                    user.setDeptName(dept.getDeptName());
                    user.setDeptId(dept.getDeptId());
                    user.setDeptAncestors(dept.getAncestors() + "," + dept.getDeptId() + ",");
                }
            }
            SysUser old = userMapper.getByKiamUserId(user.getKiamUserId());
            if (old != null) {//对存在的不更新
                continue;
            }
            if ("18392447939".equals(user.getPhonenumber())) { //超级管理员
                user.setRoleKey("admin");
                user.setRoleId(adminRole);
            } else { //普通用户 roleKey = OrdinaryBusinessPersonnel
                user.setRoleKey("OrdinaryBusinessPersonnel");
                user.setRoleId(ordinaryBusinessPersonnelRole);
            }
            if (user.getUserId() == null) {
                insertUser(user);
            } else {
                //updateUser(user, true);
            }
        }
    }


    /**
     * 数据范围过滤
     *
     * @param deptAlias 部门别名
     * @param userAlias 用户别名
     * @return
     */
    public static String dataScopeFilter(String deptAlias, String userAlias) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        StringBuilder sqlString = new StringBuilder();
        List<String> conditions = new ArrayList<String>();
        SysDept dept = user.getDept();
        for (SysRole role : user.getRoles()) {
            String dataScope = role.getDataScope();
            if (DATA_SCOPE_ALL.equals(dataScope)) {
                sqlString = new StringBuilder();
                conditions.add(dataScope);
                break;
            } else if (DATA_SCOPE_DEPT.equals(dataScope)) {
                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
                //用户所担任的部门
                List<SysDept> deptList = SpringUtil.getBean(SysDeptMapper.class).findByLeaderUserId(user.getUserId());
                deptList = deptList.stream().filter(d -> d.getDeptId().longValue() != dept.getDeptId().longValue()).collect(Collectors.toList());
                if (!deptList.isEmpty()) {
                    for (SysDept dept1 : deptList) {
                        sqlString.append(StringUtils.format(" OR {}.dept_id = {}", deptAlias, dept1.getDeptId()));
                    }
                }
            } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
                sqlString.append(StringUtils.format(
                        " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                        deptAlias, user.getDeptId(), user.getDeptId()));

                //用户所担任的部门
                List<SysDept> deptList = SpringUtil.getBean(SysDeptMapper.class).findByLeaderUserId(user.getUserId());
                deptList = deptList.stream().filter(d -> d.getDeptId().longValue() != dept.getDeptId().longValue()).collect(Collectors.toList());
                if (!deptList.isEmpty()) {
                    for (SysDept dept1 : deptList) {
                        sqlString.append(StringUtils.format(
                                " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                                deptAlias, dept1.getDeptId(), dept1.getDeptId()));
                    }
                }
            } else if (DATA_SCOPE_UNIT.equals(dataScope)) {
                sqlString.append(StringUtils.format(
                        " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE root_dept_id = {})",
                        deptAlias, dept.getRootDeptId()));
            } else if (DATA_SCOPE_SELF.equals(dataScope)) {
                if (StringUtils.isNotBlank(userAlias)) {
                    sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
                } else {
                    // 数据权限为仅本人且没有userAlias别名不查询任何数据
                    sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
                }
            }
            conditions.add(dataScope);
        }

        // 多角色情况下，所有角色都不包含传递过来的权限字符，这个时候sqlString也会为空，所以要限制一下,不查询任何数据
        if (StringUtils.isEmpty(conditions)) {
            sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
        }
        if (sqlString.length() > 10) {
            return " and (" + sqlString.toString().substring(4) + ")";
        } else {
            return "";
        }
    }

    public void waitAuditList(Page page, Map<String, Object> param) {
        addSystemParam(param);
        baseMapper.waitAuditList(page, param);
    }
}
